# -*- coding: utf-8 -*-
# RSA algorithm implementation
# See http://en.wikipedia.org/wiki/RSA_(algorithm)
#     and http://www.di-mgt.com.au/rsa_alg.html
"""RSA algorithm implementation.
See http://en.wikipedia.org/wiki/RSA_(algorithm)
    and http://www.di-mgt.com.au/rsa_alg.html

NOTICE: This program is used for learning, there may have bugs
and potential security issues. Please DO NOT use this program
in production environment.
"""
from rsa.assertfunc import param_assert_int

__author__ = 'Kainan Zhu'
__email__ = 'dlangu0393@gmail.com'
__copyright__ = 'Copyright 2013, Kainan Zhu'


def encrypt_int(plain, encrypt_key, modulus):
    """
    Encrypts plain using key
    :param encrypt_key:
        The encrypt key, e in PublicKey or d in PrivateKey.
    :param modulus:
        The RSA modulus n.
    :return:
        The cypher.
    """
    param_assert_int(plain, 'plain')
    param_assert_int(encrypt_key, 'encrypt_key')
    param_assert_int(modulus, 'modulus')

    # plain should be check in encryption
    if plain < 0:
        raise ValueError('Param plain should be a positive integer')

    if plain > modulus:
        raise ValueError('Param plain should not greater than modulus')

    # Python built-in function pow(x, y, z) can provides a efficient computation
    return pow(plain, encrypt_key, modulus)


def decrypt_int(cypher, decrypt_key, modulus):
    """
    Decrypt cypher using key
    :param decrypt_key:
        The decrypt key, e in PublicKey or d in PrivateKey.
    :param modulus:
        The RSA modulus n.
    :return:
        The plain.
    """
    param_assert_int(cypher, 'cypher')
    param_assert_int(decrypt_key, 'decrypt_key')
    param_assert_int(modulus, 'modulus')

    # Python built-in function pow(x, y, z) can provides a efficient computation
    return pow(cypher, decrypt_key, modulus)